<?php
namespace app\helpers\base;
/**
 * Created by PhpStorm.
 * User: chushangming
 * Date: 2018/1/11
 * Time: 下午3:08
 */
class Captcha
{

    protected $img;

    protected $width;

    protected $height;

    protected $fontSize;

    public $fonts;

    public $fontColor;

    public $backColor;

    public function __construct($width=160, $height=80, $fontSize=25, $fontColor='#FFF', $backColor='#000')
    {
        $this->width = $width;
        $this->height = $height;
        $this->fontSize = $fontSize;

        $type = mt_rand(1,2);
        $pngs = [
            '',
            dirname(__FILE__).'/font/1.png',
            dirname(__FILE__).'/font/2.png',
        ];
        if($type==0){

            $this->img = imagecreatetruecolor($width, $height);
        }else{

            $this->img = imagecreatefrompng($pngs[$type]);
        }
        $this->fonts = $this->getFonts();
        $this->fontColor = $this->getHexColor($fontColor);
        $this->backColor = $this->getHexColor($backColor);
        $this->createPictrue($type);
    }

    public function getResource()
    {
        return $this->img;
    }
    public function createPictrue($type=0)
    {
        if($type==0){
            $white=imagecolorallocate($this->img, 255, 255, 255);

            imagefilledrectangle($this->img, 0, 0, $this->width-1, $this->height-1, $white);
        }

        imagealphablending($this->img, true);
    }

    public function getHexColor($color)
    {
        $color = $this->hex2rgb($color);
        $color = imagecolorallocate($this->img, $color['r'], $color['g'], $color['b']);
        return $color;
    }

    public function getFonts()
    {
        return [
            dirname(__FILE__).'/font/simsun.ttc',
            dirname(__FILE__).'/font/Alabama.ttf',
        ];
    }

    public function hex2rgb($hex_str, $return_string = false, $separator = ',') {
        $hex_str = preg_replace("/[^0-9A-Fa-f]/", '', $hex_str); // Gets a proper hex string
        $rgb_array = array();
        if( strlen($hex_str) == 6 ) {
            $color_val = hexdec($hex_str);
            $rgb_array['r'] = 0xFF & ($color_val >> 0x10);
            $rgb_array['g'] = 0xFF & ($color_val >> 0x8);
            $rgb_array['b'] = 0xFF & $color_val;
        } elseif( strlen($hex_str) == 3 ) {
            $rgb_array['r'] = hexdec(str_repeat(substr($hex_str, 0, 1), 2));
            $rgb_array['g'] = hexdec(str_repeat(substr($hex_str, 1, 1), 2));
            $rgb_array['b'] = hexdec(str_repeat(substr($hex_str, 2, 1), 2));
        } else {
            return false;
        }
        return $return_string ? implode($separator, $rgb_array) : $rgb_array;
    }

    public function addDefaultText($text)
    {
        $this->addText($text,$this->backColor);
    }
    public function addText($text,$colorRGB)
    {
        $i = 0;

        $before_angle = 0;
        $before_x=0;
        for($i=0;$i< strlen($text);$i++)
        {
            $v = $text[$i];
            $this_font = mt_rand(-2,2)+$this->fontSize;
            $angle = mt_rand(-30,30);
            if($before_angle>0){
                $angle = mt_rand(-40,0);
            }
            $before_angle = mt_rand(-40,40);
            $offset_x=mt_rand(-($this->fontSize/5), -2);
            $before_x +=$offset_x;
            $x = 20+ $offset_x+$i*($this->fontSize)+$before_x;
            $x = $x >20 ? $x : 20;
            $y = mt_rand(35,40);
            imagettftext($this->img, $this_font, $angle, $x, $y, $colorRGB,  $this->fonts[mt_rand(0,1)], $v);

        }

    }

    public function addLine()
    {
        $img = $this->img;
        $width = $this->width;
        $height = $this->height;

        $stringColor = imagecolorallocate($img, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
        // 干扰
        for ($i = 0; $i < 10; $i++) {
            imagearc($img, mt_rand(-10, $width), mt_rand(-10, $height), mt_rand(30, 300), mt_rand(20, 200), 55, 44, $stringColor);
        }

        $stringColor1 = imagecolorallocate($img, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
        $stringColor2 = imagecolorallocate($img, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
        $stringColor3 = imagecolorallocate($img, mt_rand(0, 200), mt_rand(0, 120), mt_rand(0, 120));
        for ($i = 0; $i < 500; $i++) {
            $index = mt_rand(0,3);
            $colors = [$this->backColor,$stringColor1,$stringColor2,$stringColor3];

            imagesetpixel($img, mt_rand(0, $width), mt_rand(0, $height), $colors[$index]);
        }
    }

    public function output()
    {

        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Cache-Control: no-store, no-cache, must-revalidate');
        header('Cache-Control: post-check=0, pre-check=0', FALSE);
        header('Pragma: no-cache');

        header("Content-Type: image/png");


        imagepng($this->img);
    }

    public function getTypes($format)
    {
        /**
         * CS:简体中文
         * CT:繁体中文
         * E:大小英文 ENA
         * e:小写英文 ENB
         * D:数字 DIG default
         * Ee:大小写英文 ENL
         * EeD:大小英文数字 ALL
         * ED:大写数字 EAD
         * eD:小写中文 EBD
         * EUD:英文数字优化 EUD
         */
        switch ($format) {
            case 'ALL' :
                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                break;
            case 'ENL' :
                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
                break;
            case 'DIG' :
                $chars = '0123456789';
                break;
            case 'ENA' :
                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
                break;
            case 'EAD' :
                $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ123456789';
                break;
            case 'ENB' :
                $chars = 'abcdefghijklmnopqrstuvwxyz';
                break;
            case 'EBD' :
                $chars = 'abcdefghijkmnpqrstuvwxyz123456789';
                break;
            case 'EUD' :
                $chars = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'; //排除某些干扰类的数字与字母
                break;
            default:
                $chars = '0123456789';
                break;
        }
        return $chars;
    }
}